﻿using System.Collections.ObjectModel;
using System.IO;
using System.Windows;
using Chaotic.Core.Extension;
using Chaotic.DataBase.DataAccess;
using Chaotic.DataBase.DBAccessLibrary.DBAccessLibrary;
using Chaotic.DataBase.DBAccessLibrary.Model;
using Microsoft.Win32;

namespace Chaotic.Module.DBTool.ViewModels
{
    public class RegistDBViewModel: BindableBase,IDialogAware
    {
        private readonly Dictionary<string, string> _odbcDic = new();

 
        public ConnectionModel? DefaultDataSource { get; set; }
        public ConnectionModel? FileDataSource { get; set; }
        public ConnectionModel? ODBCDataSource { get; set; }

        public ObservableCollection<string> OdbcTypeCollection { get; set; } = new();
        public ObservableCollection<string> DbTypeCollection { get; set; } = new();

        public ObservableCollection<string> FileDbTypeCollection { get; set; } = new();

        private string _tabHeader;
        public string TabHeader
        {
            get => _tabHeader;
            set => this.SetProperty(ref _tabHeader, value);
        }

        private string _execFilePath;
        public string ExecFilePath
        {
            get => _execFilePath;
            set
            {
                this.SetProperty(ref _execFilePath, value);
                if(!string.IsNullOrEmpty(value))
                {
                    FileDataSource.Server = Path.GetDirectoryName(value);
                    FileDataSource.DataBase = Path.GetFileNameWithoutExtension(value);
                    switch (Path.GetExtension(value))
                    {
                        case ".xls":
                            FileDataSource.ConnectionStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + value + ";Extended Properties='Excel 8.0;HDR=Yes;IMEX=1;'";
                            break;
                        case ".xlsx":
                            FileDataSource.ConnectionStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + value + ";Extended Properties='Excel 12.0;HDR=Yes;IMEX=1;'";
                            break;
                        case ".db":
                            FileDataSource.ConnectionStr = $"Data Source={value}";
                            break;
                    }
                }
            }
        }

        public DelegateCommand SubmitCommand => new(Submit);

        public DelegateCommand CanelCommand => new(Canel);

        private void Init()
        {
            LoadDbType();
            LoadOdbc();
        }

        private void LoadOdbc()
        {
            OdbcTypeCollection.Clear();


            RegistryKey currentUser = Registry.CurrentUser;
            RegistryKey registryKey = currentUser.OpenSubKey("SoftWare");
            if (registryKey != null)
            {
                RegistryKey registryKey2 = registryKey.OpenSubKey("ODBC");
                if (registryKey2 != null)
                {
                    RegistryKey registryKey3 = registryKey2.OpenSubKey("ODBC.INI");
                    if (registryKey3 != null)
                    {
                        RegistryKey registryKey4 = registryKey3.OpenSubKey("ODBC Data Sources");
                        if (registryKey4 != null)
                        {
                            string[] valueNames = registryKey4.GetValueNames();
                            foreach (string text in valueNames)
                            {
                                _odbcDic.Add(text, registryKey4.GetValue(text).ToString());
                            }
                            OdbcTypeCollection.AddRange(registryKey4.GetValueNames());
                        }
                    }
                }
            }
            currentUser = Registry.LocalMachine;
            registryKey = currentUser.OpenSubKey("SoftWare");
            if (registryKey != null)
            {
                RegistryKey registryKey5 = registryKey.OpenSubKey("ODBC");
                if (registryKey5 != null)
                {
                    RegistryKey registryKey6 = registryKey5.OpenSubKey("ODBC.INI");
                    if (registryKey6 != null)
                    {
                        RegistryKey registryKey7 = registryKey6.OpenSubKey("ODBC Data Sources");
                        if (registryKey7 != null)
                        {
                            string[] valueNames2 = registryKey7.GetValueNames();
                            foreach (string text2 in valueNames2)
                            {
                                _odbcDic.Add(text2, registryKey7.GetValue(text2).ToString());
                            }
                            OdbcTypeCollection.AddRange(registryKey7.GetValueNames());
                        }
                    }
                }
            }
            

        }
        private void LoadDbType()
        {
            DbTypeCollection.Clear();
            DbTypeCollection.AddRange(Enum.GetNames(typeof(DatabaseType)).Where(x => x != nameof(DatabaseType.OleDBSupported) && x != nameof(DatabaseType.ODBC) && x != nameof(DatabaseType.Sqlite)));

            FileDbTypeCollection.Clear();
            FileDbTypeCollection.AddRange(Enum.GetNames(typeof(DatabaseType)).Where(x => x == nameof(DatabaseType.OleDBSupported) || x == nameof(DatabaseType.Sqlite)));
        }


        private bool TestConnection(ConnectionModel? connectionModel)
        {
            try
            {

                string text = DBOperatorFactory.GetOperator.IsConnectDB(connectionModel);
                if (text == string.Empty)
                {
                    return true;
                }

                MessageBox.Show(text);
                return false; 
            }
            catch (Exception ex)
            {
                MessageBoxExtension.ShowError(ex.Message);
                return false;
            }
        }

        public void SetData(ConnectionModel model)
        {
            if(model.ConnectType == DatabaseType.OleDBSupported || model.ConnectType == DatabaseType.Sqlite)
            {
                FileDataSource.ConnectType = model.ConnectType;
                FileDataSource.ConnectionStr = model.ConnectionStr;
            }
            else if(model.ConnectType == DatabaseType.ODBC)
            {
                ODBCDataSource.ConnectType = model.ConnectType;
                ODBCDataSource.Server = model.Server;
                ODBCDataSource.DataBase = model.DataBase;
                ODBCDataSource.UserID = model.UserID;
                ODBCDataSource.PassWord = model.PassWord;
                ODBCDataSource.ConnectionStr = model.ConnectionStr;
            }
            else
            {
                DefaultDataSource.ConnectType = model.ConnectType;
                DefaultDataSource.Server = model.Server;
                DefaultDataSource.DataBase = model.DataBase;
                DefaultDataSource.UserID = model.UserID;
                DefaultDataSource.PassWord = model.PassWord;
                DefaultDataSource.ConnectionStr = model.ConnectionStr;
            }
           
        }

        private void Canel()
        {
            RequestClose.Invoke(new DialogResult(ButtonResult.Cancel));
        }
        private void Submit()
        {
            ConnectionModel? connectionModel = null;
            switch (TabHeader)
            {
                case "常用连接":
                    if (DefaultDataSource.DataBase == null || DefaultDataSource.UserID == null || DefaultDataSource.Server == null)
                    {
                        MessageBoxExtension.Show("数据库基本数据不完全，请查看");
                        return;
                    }
                    connectionModel = DefaultDataSource;
                    break;
                case "文件":
                    if (string.IsNullOrEmpty(FileDataSource.DataBase) || string.IsNullOrEmpty(FileDataSource.ConnectionStr))
                    {
                        MessageBoxExtension.Show("数据库基本数据不完全，请查看");
                        return;
                    }
                    connectionModel = FileDataSource;
                    break;
                case "ODBC":
                    if (string.IsNullOrEmpty(ODBCDataSource.DataBase) || string.IsNullOrEmpty(ODBCDataSource.ConnectionStr))
                    {
                        MessageBoxExtension.Show("数据库基本数据不完全，请查看");
                        return;
                    }
                    connectionModel = ODBCDataSource;
                    break;
            }

            if(connectionModel == null)
            {
                return;
            }

            if (!TestConnection(connectionModel))
                return;

            IDialogParameters parameters = new DialogParameters();
            parameters.Add("result", connectionModel);
            RequestClose.Invoke(parameters,ButtonResult.OK);
        }
 

        #region IDialogAware

        public string Title { get; set; } =  "连接数据源";

        //public ConnectionModel Result { get; set; }

        private double _maxWidth = 400.0;
        public double MaxWidth
        {
            get => _maxWidth;
            set => this.SetProperty(ref _maxWidth, value);
        }

        public DialogCloseListener RequestClose { get; set; }

        /// <summary>
        /// 允许用户手动关闭窗口
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public bool CanCloseDialog()
        {
            return true;
        }

        public void OnDialogClosed()
        {
            //当关闭窗口时触发

        }

        public void OnDialogOpened(IDialogParameters parameters)
        { 
            Init();
            //接收窗体打开时的参数内容
            DefaultDataSource = new ConnectionModel()
            {
                ConnectType = DatabaseType.MSSQLServer,
                Server = "127.0.0.1",
                UserID = "sa", 
                DataBase = "ams",
                PassWord = "123456",
            };

            FileDataSource = new ConnectionModel()
            {
                ConnectType = DatabaseType.OleDBSupported
            };

            ODBCDataSource = new ConnectionModel()
            {
                ConnectType = DatabaseType.ODBC
            };
        }

        #endregion
    }
}
